Load packages

library(httr)
library(jsonlite)
library(tidyverse)
library(dplyr)
library(ggplot2)
library(tableone)
library(kableExtra)
library(plotly)
library(devtools)

Introduction

  1. What are the five countries with the highest number of registered adverse events

  2. Differences in occurance and percentage of adverse events among those countries

  3. Differences in occurance and percentage of adverse events among different age groups across all patients taking Imfinzi globally

  4. Differences in occurance and percentage of adverse events between patients taking Imfinzi and Tecentriq (Atezolizumab), another cancer immunotherapy treatment

openFDA data

Data Quality

Existence of a report does not establish causation

Information in reports has not been verified

Rates of occurrence cannot be established with reports

Patient Outcomes received in FAERS

Strenghs

Limitations

Downloading openFDA data

search=patient.drug.medicinalproduct:"durvalumab+imfinzi" 
count=patient.reaction.reactionmeddrapt.exact

Number of reports by country

res = GET("https://api.fda.gov/drug/event.json?search=receivedate:[20140101+TO+20200729]+AND+(patient.drug.medicinalproduct:'durvalumab+imfinzi')&count=occurcountry.exact")

rawToChar(res$content)

data = fromJSON(rawToChar(res$content))

dt_country= data$results %>% 
        as_tibble() %>%
        slice_head(n=15)
p = ggplot(data=dt_country, aes(x= reorder(term, count), y=count, width=0.8)) +
        geom_bar(stat = "identity", fill="blue") +
        labs(y="Number of cases", x="Countries") +
        geom_text(aes(label=count), hjust=-0.3, size=3) +
        theme_classic() +
        coord_flip() 
p

Adverse events reports by country

#Get US data
res = GET("https://api.fda.gov/drug/event.json?search=receivedate:[20140101+TO+20200729]+AND+(patient.drug.medicinalproduct:'durvalumab+imfinzi')+AND+occurcountry:'US'&count=patient.reaction.reactionmeddrapt.exact")

rawToChar(res$content)

data = fromJSON(rawToChar(res$content))

US_ae= data$results %>%
        mutate(country="US") %>%
        mutate(Percentage = 100*count/sum(count)) 

#Get JP data
res = GET("https://api.fda.gov/drug/event.json?search=receivedate:[20140101+TO+20200729]+AND+(patient.drug.medicinalproduct:'durvalumab+imfinzi')+AND+occurcountry:'JP'&count=patient.reaction.reactionmeddrapt.exact")

rawToChar(res$content)

data = fromJSON(rawToChar(res$content))

JP_ae= data$results %>%
        mutate(country="JP") %>%
        mutate(Percentage = 100*count/sum(count)) 

#Get CA data
res = GET("https://api.fda.gov/drug/event.json?search=receivedate:[20140101+TO+20200729]+AND+(patient.drug.medicinalproduct:'durvalumab+imfinzi')+AND+occurcountry:'CA'&count=patient.reaction.reactionmeddrapt.exact")

rawToChar(res$content)

data = fromJSON(rawToChar(res$content))

CA_ae= data$results %>%
        mutate(country="CA") %>%
        mutate(Percentage = 100*count/sum(count)) 


#Get FR data
res = GET("https://api.fda.gov/drug/event.json?search=receivedate:[20140101+TO+20200729]+AND+(patient.drug.medicinalproduct:'durvalumab+imfinzi')+AND+occurcountry:'FR'&count=patient.reaction.reactionmeddrapt.exact")

rawToChar(res$content)

data = fromJSON(rawToChar(res$content))

FR_ae= data$results %>%
        mutate(country="FR") %>%
        mutate(Percentage = 100*count/sum(count)) 

#Get DE data
res = GET("https://api.fda.gov/drug/event.json?search=receivedate:[20140101+TO+20200729]+AND+(patient.drug.medicinalproduct:'durvalumab+imfinzi')+AND+occurcountry:'DE'&count=patient.reaction.reactionmeddrapt.exact")

rawToChar(res$content)

data = fromJSON(rawToChar(res$content))

DE_ae= data$results %>%
        mutate(country="DE") %>%
        mutate(Percentage = 100*count/sum(count)) 

#Combine the data sets and select the top 10 reports by country
ae_all = bind_rows(US_ae, JP_ae, CA_ae, FR_ae, DE_ae) %>%
        mutate(text = paste0("Country: ", country, "\n", "Reaction: ", term, "\n", "Percentage: ", round(Percentage,2))) %>%
        group_by(country) %>%
        slice_head(n=10) %>%
        ungroup()

US

p = ggplot(data=US_ae %>% slice_head(n=10), aes(x= reorder(term, count), y=count, width=.8)) +
        geom_bar(stat = "identity", fill="blue") +
        expand_limits(y = 150) +
        labs(y="Number of cases", x="") +
        geom_text(aes(label=count), hjust=-0.3, size=3) +
        theme_classic() +
        coord_flip()
p

Japan

p = ggplot(data=JP_ae %>% slice_head(n=10) , aes(x= reorder(term, count), y=count, width=.8)) +
        geom_bar(stat = "identity", fill="blue") +
        expand_limits(y = 310) +
        labs(y="Number of cases", x="") +
        geom_text(aes(label=count), hjust=-0.3, size=3) +
        theme_classic()+ 
        coord_flip() 
p

Canada

p = ggplot(data=CA_ae %>% slice_head(n=10), aes(x= reorder(term, count), y=count, width=.8)) +
        geom_bar(stat = "identity", fill="blue") +
        labs(y="Number of cases", x="") +
        geom_text(aes(label=count), hjust=-0.3, size=3) +
        theme_classic() +
        coord_flip()
p

France

p = ggplot(data=FR_ae %>% slice_head(n=10), aes(x= reorder(term, count), y=count, width=.8)) +
        geom_bar(stat = "identity", fill="blue") +
        labs(y="Number of cases", x="") +
        geom_text(aes(label=count), hjust=-0.3, size=3) +
        theme_classic() +
        coord_flip()
p

Germany

p = ggplot(data=DE_ae %>% slice_head(n=10), aes(x= reorder(term, count), y=count, width=.8)) +
        geom_bar(stat = "identity", fill="blue") +
        labs(y="Number of cases", x="") +
        geom_text(aes(label=count), hjust=-0.3, size=3) +
        theme_classic() +
        coord_flip()
p

Interactive heatmap of adverse events by country

p = ggplot(ae_all, aes(country, term, fill=Percentage, text=text)) +
        geom_tile() + 
        labs(y="", x="Countries") +
        theme_classic()
ggplotly(p, tooltip = "text")

Adverse events by age globally

#18-49
res = GET("https://api.fda.gov/drug/event.json?search=receivedate:[20140101+TO+20200729]+AND+(patient.drug.medicinalproduct:'durvalumab+imfinzi')+AND+patient.patientonsetage:[18+TO+49]&count=patient.reaction.reactionmeddrapt.exact")

rawToChar(res$content)

data = fromJSON(rawToChar(res$content))

dt_adult= data$results %>% 
        as_tibble() %>%
        mutate(age = "18-49") %>%
        mutate(Percentage = 100*count/sum(count)) 

#50-64
res = GET("https://api.fda.gov/drug/event.json?search=receivedate:[20140101+TO+20200729]+AND+(patient.drug.medicinalproduct:'durvalumab+imfinzi')+AND+patient.patientonsetage:[50+TO+64]&count=patient.reaction.reactionmeddrapt.exact")


rawToChar(res$content)

data = fromJSON(rawToChar(res$content))

dt_middle= data$results %>% 
        as_tibble() %>%
        mutate(age = "50-64") %>%
        mutate(Percentage = 100*count/sum(count))

#65-100
res = GET("https://api.fda.gov/drug/event.json?search=receivedate:[20140101+TO+20200729]+AND+(patient.drug.medicinalproduct:'durvalumab+imfinzi')+AND+patient.patientonsetage:[65+TO+100]&count=patient.reaction.reactionmeddrapt.exact")


rawToChar(res$content)

data = fromJSON(rawToChar(res$content))

dt_elderly= data$results %>% 
        as_tibble() %>%
        mutate(age = "65-100") %>%
        mutate(Percentage = 100*count/sum(count))

#Missing age

res = GET("https://api.fda.gov/drug/event.json?search=receivedate:[20140101+TO+20200729]+AND+(patient.drug.medicinalproduct:'durvalumab+imfinzi')+AND+_missing_:patient.patientonsetage&count=patient.reaction.reactionmeddrapt.exact")


rawToChar(res$content)

data = fromJSON(rawToChar(res$content))

dt_age_missing= data$results %>% 
        as_tibble() %>%
        mutate(age = "Unknown") %>%
        mutate(Percentage = 100*count/sum(count))


ae_age = bind_rows(dt_adult, dt_middle, dt_elderly, dt_age_missing) %>%
        mutate(text = paste0("Age: ", age, "\n", "Reaction: ", term, "\n", "Percentage: ", round(Percentage,2))) %>%
        group_by(age) %>%
        slice_head(n=10) %>%
        ungroup()


age_aux = bind_rows(dt_adult,  dt_middle, dt_elderly, dt_age_missing) %>%
        group_by(age) %>%
        summarise(total = sum(count)) %>%
        ungroup()
## `summarise()` ungrouping output (override with `.groups` argument)

Summary of adverse event reported by age groups

  • The age group 65-100 has the highest number of cases, while the age group 18-49 has the lowest

  • A significant proportion of cases has missing age

p = ggplot(data=age_aux, aes(x= age, y=total)) +
        geom_bar(stat = "identity", fill="blue") +
        labs(x="Age group", y="Number of cases") +
        geom_text(aes(label=total), hjust=-0.3, size=3) +
        theme_classic() +
        expand_limits(y = 1350) +
        coord_flip() 
p

Interactive heatmap of adverse events by age group

p = ggplot(ae_age, aes(age, term, fill=Percentage, text=text)) +
        geom_tile() + 
        labs(x="Age group", y="") +
        theme_classic()
ggplotly(p, tooltip = "text")

Imfinzi versus Tecentriq

# Atezo
res = GET("https://api.fda.gov/drug/event.json?search=receivedate:[20140101+TO+20200729]+AND+(patient.drug.medicinalproduct:'atezolizumab+tecentriq')&count=patient.reaction.reactionmeddrapt.exact")

rawToChar(res$content)

data = fromJSON(rawToChar(res$content))

dt_tec= data$results %>% 
        as_tibble() %>%
        mutate(Treatment = "Tecentriq") %>%
        mutate(Percentage = 100*count/sum(count)) 

# Durva
res = GET("https://api.fda.gov/drug/event.json?search=receivedate:[20140101+TO+20200729]+AND+(patient.drug.medicinalproduct:durvalumab+imfinzi)&count=patient.reaction.reactionmeddrapt.exact")

rawToChar(res$content)

data = fromJSON(rawToChar(res$content))

dt_durva= data$results %>% 
        as_tibble() %>%
        mutate(Treatment = "Imfinzi") %>%
        mutate(Percentage = 100*count/sum(count)) 



ae_tec_durva = bind_rows(dt_tec, dt_durva) %>%
        mutate(text = paste0("Treatment: ", Treatment, "\n", "Reaction: ", term, "\n", "Percentage: ", round(Percentage,2))) %>%
        group_by(Treatment) %>%
        slice_head(n=10) %>%
        ungroup()

Interactive heatmap of adverse events by treatment

  • Radiation pneumonitis does not appear in the top ten adverse events for Tecentriq patients. However, it is one of the most commun for Imfinzi patients

  • The percentages of deaths is similar between both treatment groups

p = ggplot(ae_tec_durva, aes(Treatment, term, fill=Percentage, text=text)) +
        geom_tile() + 
        labs(x="Age group", y="") +
        theme_classic()
ggplotly(p, tooltip = "text")

Environment

session = sessionInfo()
session$R.version$version.string
## [1] "R version 3.6.0 (2019-04-26)"
session$R.version$platform
## [1] "x86_64-apple-darwin15.6.0"
session$running
## [1] "macOS High Sierra 10.13.6"

Reference